﻿package idv.cjcat.emitter.behaviors {
	use namespace engine;
	
	import flash.errors.*;
	
	import idv.cjcat.emitter.*;
	
	/**
	 * Abstract behavior trigger.
	 * <p>
	 * This is an abstarct class and should not be instantiated.
	 * </p>
	 */
	public class BehaviorTrigger implements IEmitterXML, IEmitterDestructible {
		public var active:Boolean = true;
		
		/** @private */
		engine var _behaviors:Vector.<Behavior> = new Vector.<Behavior>();
		
		public function BehaviorTrigger() {
			this.id = null;
		}
		
		/**
		 * This is an abstract method and should be overriden.
		 */
		public function test(pd:ParticleData):Boolean {
			return true;
		}
		
		engine function behave(pd:ParticleData):void {
			for each (var b:Behavior in _behaviors) {
				if (b._destroyed) EmitterGlobal.throwDestroyedObjectError(b);
				
				if (b.active) b.behave(pd);
			}
		}
		
		/**
		 * Adds a behavior.
		 * @param	behavior
		 */
		public function addBehavior(behavior:Behavior):void {
			removeBehavior(behavior);
			_behaviors.push(behavior);
		}
		/**
		 * Removes a behavior.
		 * @param	behavior
		 */
		public function removeBehavior(behavior:Behavior):void {
			var index:int = _behaviors.indexOf(behavior);
			if (index >= 0) _behaviors.splice(index, 1);
		}
		/**
		 * Removes all behaviors.
		 * @return The original behaviors.
		 */
		public function clearBehaviors():Vector.<Behavior> {
			var temp:Vector.<Behavior> = _behaviors;
			_behaviors = new Vector.<Behavior>();
			return temp;
		}
		
		
		//IEmitterDestructible
		//------------------------------------------------------------------------------------------------
		
		engine var _destroyed:Boolean = false;
		public function get destroyed():Boolean { return _destroyed }
		
		//------------------------------------------------------------------------------------------------
		//end of IEmitterDestructible
		
		
		//XML
		//------------------------------------------------------------------------------------------------
		
		/** @private */
		engine var _id:String;
		public function get id():String { return _id; }
		public function set id(value:String):void {
			delete EmitterGlobal._behaviorTriggers[_id];
			if (value == null) {
				while (EmitterGlobal._behaviorTriggers["behaviorTrigger" + EmitterGlobal._behaviorTriggerCounter] != undefined) {
					EmitterGlobal._behaviorTriggerCounter++;
				}
				_id = "behaviorTrigger" + EmitterGlobal._behaviorTriggerCounter;
			} else {
				if (EmitterGlobal._behaviorTriggers[value] == undefined) {
					_id = value;
				} else {
					throw new IllegalOperationError("This name is already used by another behavior trigger.");
				}
			}
			EmitterGlobal._behaviorTriggers[_id] = this;
		}
		public function toXML():XML {
			var xml:XML = <behaviorTrigger/>;
			xml.@id = _id;
			xml.@type = "abstract";
			xml.@active = active.toString();
			
			var behaviorsXML:XML = <behaviors/>;
			for each (var b:Behavior in _behaviors) {
				var bID:XML = <id/>;
				bID.@value = b._id;
				behaviorsXML.appendChild(bID);
			}
			xml.appendChild(behaviorsXML);
			
			return xml;
		}
		public function parseXML(xml:XML):void {
			active = (xml.@active == "true");
			for each (var node:XML in xml.behaviors.id) {
				addBehavior(EmitterGlobal.getBehaviorByID(node.@value));
			}
		}
		
		//------------------------------------------------------------------------------------------------
		//end of XML
	}
}